home *** CD-ROM | disk | FTP | other *** search
- /*
- * Nice Numbers for Graph Labels
- * by Paul Heckbert
- * from "Graphics Gems", Academic Press, 1990
- */
-
- /*
- * label.c: demonstrate nice graph labeling
- *
- * Paul Heckbert 2 Dec 88
- */
-
- #include "GraphicsGems.h"
- #include <stdio.h>
- #include <math.h>
-
- double nicenum();
-
- /* expt(a,n)=a^n for integer n */
-
- #ifdef POW_NOT_TRUSTWORTHY
- /* if roundoff errors in pow cause problems, use this: */
-
- double expt(a, n)
- double a;
- register int n;
- {
- double x;
-
- x = 1.;
- if (n>0) for (; n>0; n--) x *= a;
- else for (; n<0; n++) x /= a;
- return x;
- }
-
- #else
- #define expt(a, n) pow(a, (double)(n))
- #endif
-
-
- #define NTICK 5 /* desired number of tick marks */
-
- main(ac, av)
- int ac;
- char **av;
- {
- double min, max;
-
- if (ac!=3) {
- fprintf(stderr, "Usage: label <min> <max>\n");
- exit(1);
- }
- min = atof(av[1]);
- max = atof(av[2]);
- loose_label(min, max);
- }
-
- /*
- * loose_label: demonstrate loose labeling of data range from min to
- * max. (tight method is similar)
- */
-
- loose_label(min, max)
- double min, max;
- {
- char str[6], temp[20];
- int nfrac;
- double d; /* tick mark spacing */
- double graphmin, graphmax; /* graph range min and max */
- double range, x;
-
- /* we expect min!=max */
- range = nicenum(max-min, 0);
- d = nicenum(range/(NTICK-1), 1);
- graphmin = floor(min/d)*d;
- graphmax = ceil(max/d)*d;
- nfrac = MAX(-floor(log10(d)), 0);
- /* # of fractional digits to show */
- sprintf(str, "%%.%df", nfrac); /* simplest axis labels */
-
- printf("graphmin=%g graphmax=%g increment=%g\n",
- graphmin, graphmax, d);
- for (x=graphmin; x<graphmax+.5*d; x+=d) {
- sprintf(temp, str, x);
- printf("(%s)\n", temp);
- }
- }
-
-
- /*
- * nicenum: find a "nice" number approximately equal to x.
- * Round the number if round=1, take ceiling if round=0
- */
-
- static double nicenum(x, round)
- double x;
- int round;
- {
- int exp; /* exponent of x */
- double f; /* fractional part of x */
- double nf; /* nice, rounded fraction */
-
- exp = floor(log10(x));
- f = x/expt(10., exp); /* between 1 and 10 */
- if (round)
- if (f<1.5) nf = 1.;
- else if (f<3.) nf = 2.;
- else if (f<7.) nf = 5.;
- else nf = 10.;
- else
- if (f<=1.) nf = 1.;
- else if (f<=2.) nf = 2.;
- else if (f<=5.) nf = 5.;
- else nf = 10.;
- return nf*expt(10., exp);
- }
-